package springRepo.Library.repository.author;

import static springRepo.Library.repository.jdbc.DAOJDBCUtil.close;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import springRepo.Library.domain.author.Author;

@Repository("AuthorRepository")
public class AuthorRepositoryJDBC implements AuthorRepository {

	private static final Logger LOGGER = Logger.getLogger(AuthorRepositoryJDBC.class.getCanonicalName());
	
	private DataSource ds;
	
	@Autowired
	public AuthorRepositoryJDBC(DataSource ds){
		this.ds = ds;
	}
	
	public Author find(Integer id) {
		Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        Author author = null;
        
        try {
            connection = ds.getConnection();
            preparedStatement = connection.prepareStatement("select * from Author where id=?");
            preparedStatement.setInt(1, id);
            resultSet = preparedStatement.executeQuery();
            if (resultSet.next()) {
                author = (map(resultSet));
            }
        } catch (SQLException e) {
        	LOGGER.log(Level.SEVERE, e.getMessage());
        } finally {
            close(resultSet);
            close(preparedStatement);
            close(connection);
        }

        return author;
	}

	public List<Author> findAll() {
		Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        List<Author> authors = new ArrayList<Author>();

        try {
            connection = ds.getConnection();
            preparedStatement = connection.prepareStatement("select * from Author");
            resultSet = preparedStatement.executeQuery();
            while (resultSet.next()) {
                authors.add(map(resultSet));
            }
        } catch (SQLException e) {
        	LOGGER.log(Level.SEVERE, e.getMessage());
        } finally {
            close(resultSet);
            close(preparedStatement);
            close(connection);
        }

        return authors;
	}

	public boolean create(Author author) {
		Connection connection = null;
        PreparedStatement preparedStatement = null;
        try {
            connection = ds.getConnection();
            preparedStatement = connection.prepareStatement("INSERT INTO Author "
                    + "(name, birthYear, deathYear) VALUES (?, ?, ?)");
            preparedStatement.setString(1, author.getName());
            preparedStatement.setInt(2, author.getBirthYear());
            preparedStatement.setInt(3, author.getDeathYear());
            preparedStatement.execute();
            return true;
        } catch (SQLException e) {
        	LOGGER.log(Level.SEVERE, e.getMessage());
        } finally {
            close(preparedStatement);
            close(connection);
        }
        return false;
	}

	public Author findByName(String authorName) {
		Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        Author author = null;

        try {
            connection = ds.getConnection();
            preparedStatement = connection.
                    prepareStatement("select * from Author where name = ?");
            preparedStatement.setString(1, authorName);
            resultSet = preparedStatement.executeQuery();
                      
            if(resultSet.next()) {
                author = map(resultSet);
            }
        } catch (SQLException e) {
        	LOGGER.log(Level.SEVERE, e.getMessage());
        } finally {
            close(resultSet);
            close(preparedStatement);
            close(connection);
        }

        return author;
	}

	private Author map(ResultSet resultSet) throws SQLException {
        Author author = new Author();
        author.setName(resultSet.getString(2));
        author.setBirthYear(resultSet.getInt(3));
        author.setDeathYear(resultSet.getInt(4));
        return author;
    }
}
